<template>
  <el-dialog
    v-model="visible"
    :title="title"
    :width="width"
    @close="handleClose"
  >
    <el-descriptions
      :column="column"
      :size="size"
      border
    >
      <template v-for="field in fields" :key="field.prop">
        <el-descriptions-item
          v-if="!field.hidden"
          :label="field.label"
          :span="field.span"
          :width="field.width"
          :min-width="field.minWidth"
          :align="field.align"
          :label-align="field.labelAlign"
        >
          <!-- 自定义插槽 -->
          <slot
            v-if="field.slot"
            :name="field.slot"
            :field="field"
            :data="data"
          />
          <!-- 默认显示 -->
          <template v-else>
            {{ formatValue(data[field.prop], field) }}
          </template>
        </el-descriptions-item>
      </template>
    </el-descriptions>
    
    <template #footer>
      <slot name="footer">
        <el-button @click="handleClose">关闭</el-button>
      </slot>
    </template>
  </el-dialog>
</template>

<script setup lang="ts">
// 字段配置类型
interface FieldConfig {
  prop: string
  label: string
  span?: number
  width?: string
  minWidth?: string
  align?: 'left' | 'center' | 'right'
  labelAlign?: 'left' | 'center' | 'right'
  hidden?: boolean
  slot?: string
  formatter?: (value: any, field: FieldConfig) => any
}

interface Props {
  visible: boolean
  title?: string
  width?: string
  data: Record<string, any>
  fields: FieldConfig[]
  column?: number
  size?: 'large' | 'default' | 'small'
}

const props = withDefaults(defineProps<Props>(), {
  title: '详情',
  width: '500px',
  column: 1,
  size: 'default'
})

interface Emits {
  (e: 'update:visible', value: boolean): void
  (e: 'close'): void
}

const emit = defineEmits<Emits>()

const visible = computed({
  get: () => props.visible,
  set: (value) => emit('update:visible', value)
})

const formatValue = (value: any, field: FieldConfig) => {
  if (field.formatter) {
    return field.formatter(value, field)
  }
  return value
}

const handleClose = () => {
  emit('close')
  visible.value = false
}
</script>